package lowijs.XfDroid;

import java.io.File;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;

import android.util.Log;

import lowijs.XfireClient.util.Util;

/**
 * This class will intercept errors and log them to the SD card for later
 * debuging.
 * @author sgaines
 */
public class ErrorHandler implements UncaughtExceptionHandler {
	private UncaughtExceptionHandler delegate;

	private ErrorHandler(UncaughtExceptionHandler delegate) {
		this.delegate = delegate;
	}

	/**
	 * Write the stack trace to the SD card, then forward to the delegate.
	 */
	public void uncaughtException(Thread thread, Throwable t) {
		Log.e(XfDroidConstants.LOG_TAG, t.getMessage(), t);
		write(t);
		delegate.uncaughtException(thread, t);
	}

	public static void write(Throwable t) {
		File file = Util.getFile("crash/" + Util.FORMAT.format(new Date()));

		if (file != null) {
			try {
				file.getParentFile().mkdirs();
				PrintWriter writer = new PrintWriter(file);
				t.printStackTrace(writer);
				writer.close();
			} catch (Exception e) {
			}
		}
	}

	/**
	 * This method will install an ErrorHandler if it hasn't already been set.
	 * Otherwise this method does nothing.
	 */
	public static void install() {
		UncaughtExceptionHandler previous = Thread.getDefaultUncaughtExceptionHandler();

		if (!(previous instanceof ErrorHandler)) {
			Thread.setDefaultUncaughtExceptionHandler(new ErrorHandler(previous));

			File dir = Util.getFile("crash");

			if (dir.exists()) {
				File[] files = dir.listFiles();
				Arrays.sort(files, new Comparator<File>() {
					public int compare(File f1, File f2) {
						if (f1.lastModified() < f2.lastModified()) {
							return -1;
						} else if (f1.lastModified() > f2.lastModified()) {
							return 1;
						}

						return 0;
					}
				});

				// remove all but last 10
				for (int i=0, n=files.length - 10; i<n; i++) {
					files[i].delete();
				}
			}
		}
	}
}
